home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / program / ixemlsrc.lha / ixemul / library / __read.c < prev    next >
C/C++ Source or Header  |  1995-12-31  |  4KB  |  128 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  __read.c,v 1.1.1.1 1994/04/04 04:30:12 amiga Exp
  20.  *
  21.  *  __read.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:12  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.1  1992/05/14  19:55:40  mwild
  26.  *  Initial revision
  27.  *
  28.  */
  29.  
  30. #define KERNEL
  31. #include "ixemul.h"
  32. #include "kprintf.h"
  33.  
  34. /*
  35.  * Starting with ixemul 42.0 we switched from asynchronous to synchronous
  36.  * reads.  Apparently the ADOS CON handler uses the mp_SigTask field of the
  37.  * MsgPort struct of a ACTION_READ package to find the Task which it should
  38.  * signal when the user presses Ctrl-C.  However, async reads use a special
  39.  * port where the mp_SigTask field points to an Interrupt struct.  The CON
  40.  * handler seems to either use that address as the new Task pointer (I hope
  41.  * not) or disable Ctrl-C signalling entirely.  I never noticed this until it
  42.  * was pointed out to me, since I always use KingCON. KingCON seems to handle
  43.  * Ctrl-C differently. Just to be sure I also changed the ACTION_WAIT_CHAR
  44.  * to synchronous mode.
  45.  */
  46.  
  47. int __read(struct file *f, char *buf, int len)
  48. {
  49.   int err=errno, res = 0;
  50.   int omask;
  51.   char *orig_buf = buf;
  52.  
  53.   /* always return EOF */
  54.   if (HANDLER_NIL(f)) return 0;
  55.  
  56.   omask = syscall (SYS_sigsetmask, ~0);
  57.   __get_file (f);
  58.   /* just to make sure, this packet is really free, it could have
  59.    * been used by a semi-async write, eg. */
  60.   __wait_packet(&f->f_sp);
  61.  
  62.   if (len > 0)
  63.     {
  64.       if (f->f_flags & FNDELAY)
  65.     {
  66.       /* shudder.. this is the most inefficient part of the whole
  67.        * library, but I don't know of another way of doing it... */
  68.       while (res < len)
  69.             {
  70.               SendPacket1(f, __srwport, ACTION_WAIT_CHAR, 10);
  71.               __wait_sync_packet(&f->f_sp);
  72.               if (! LastResult(f))
  73.               {
  74.                 if (!res)
  75.                 {
  76.                   res = -1;
  77.                   err = EAGAIN;
  78.                 }
  79.                 break;
  80.               }
  81.           SendPacket3(f, __srwport, ACTION_READ, f->f_fh->fh_Arg1, (long)buf, 1);
  82.           __wait_sync_packet(&f->f_sp);
  83.           if (LastResult(f) != 1) 
  84.         {
  85.           err = __ioerr_to_errno(LastError(f));
  86.           /* if there really was no character to read, we should
  87.            * have escaped already at the 'if WaitForChar' line */
  88.           res = -1;
  89.           break;
  90.         }
  91.           buf++;
  92.           res++;
  93.         }
  94.     }      
  95.       else
  96.     {
  97.       SendPacket3(f, __srwport, ACTION_READ, f->f_fh->fh_Arg1, (long)buf, len);
  98.       __wait_sync_packet(&f->f_sp);
  99.       res = LastResult(f);
  100.       if (res == -1)
  101.         err = __ioerr_to_errno(LastError(f));
  102.     }
  103.    }
  104.  
  105.   LastResult(f) = 0;
  106.   __release_file (f);
  107.   syscall (SYS_sigsetmask, omask);
  108.   errno = err;
  109.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  110.   
  111.   /*  If we read something from a file, and the file is opened RAW (e.g., a stdin
  112.    *  stream in RAW mode), then we replace all '\r' characters with '\n' characters.
  113.    *  This is a courtesy for those programs that turn off ECHO for the input of a
  114.    *  password. Turning off ECHO sets the input mode to RAW, and in RAW mode the
  115.    *  Enter key inserts a '\r' into the stream. However, the stdio functions expect
  116.    *  a '\n' to end a line, so we patch the input buffer.
  117.    */
  118.   if (res > 0 && (f->f_flags & FTTYRAW) && (f->f_flags & FTTYCRNL))
  119.     {
  120.       int i;
  121.  
  122.       for (i = 0; i < res; i++)
  123.         if (orig_buf[i] == '\r')
  124.           orig_buf[i] = '\n';
  125.     }
  126.   return res;
  127. }
  128.